<template>
    <div class="el-main main-content">
        <div class="article banner top">
            <div class="content">
                <div class="top bread-nav footnote">
                    <div class="left">
                        <div class="flex-row" id="breadcrumb">
                            <a class="cap breadcrumb" v-if="article.type === 1" href="/">原创</a>
                            <a class="cap breadcrumb" v-if="article.type === 2" href="/">转载</a>
                            <a class="cap breadcrumb" v-if="article.type === 3" href="/">翻译</a>
                            <span class="sep"></span><a class="cap breadcrumb" id="menu"
                                href="/topic">{{ article.categoryName }}</a><span class="sep"></span><a
                                class="cap breadcrumb" id="proj" v-show="article.type === 2 || article.type === 3"
                                :href="article.original_url">点击查看原文</a>
                        </div>
                        <div class="flex-row" id="post-meta"><a class="author" href="/author/ThatCoder/">安奈博客🌙</a><span
                                class="sep"></span><span class="text created"><time
                                    datetime="2024-06-10T02:01:00.000Z">{{ formatDate(article.createTime)
                                    }}</time></span><span class="sep updated"></span><span
                                class="text updated">更新于：<time datetime="2024-08-11T17:49:55.119Z">{{
                                    Math.ceil(Math.abs(new Date(article.createTime) - new
                                    Date(article.updateTime))/(1000*3600*24)) }}天前</time></span></div>
                    </div>
                </div>
                <div class="bottom only-title">
                    <div class="text-area">
                        <h1 class="text title"><span>{{ article.articleTitle }}</span></h1>
                    </div>
                </div>
            </div>
        </div>
        <div class="content">
            <article class="md-text">
                <div v-html="renderedMarkdown"></div>
            </article>
        </div>
    </div>
</template>
<script>
import { marked } from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'; // 引入样式  
import { getOneByArticleId } from '@/api/article';
export default {
    data() {
        return {
            id: '',
            article: {},
            markdownText: '', // 初始化为空字符串，而不是 '11'  
            renderedMarkdown: '',
            openText: '<i class="fa-solid fa-angles-down fa-beat-fade"></i>',
            closeText: '<i class="fa-solid fa-angles-up fa-beat-fade"></i>',
            fullOpen: '<i class="fa-solid fa-expand"></i>',
            fullClose: '<i class="fa-solid fa-compress"></i>',
            copyText: '<i class="fa-solid fa-window-restore"></i>',
            copySuccess: '<i class="fa-solid fa-check-double"></i>',
            downTest: '<i class="fa-solid fa-download"></i>',
            FileSize: '120kb',

        }
    },
    mounted() {
        // 获取文章内容
        getOneByArticleId(this.$route.params.id).then((res) => {
            this.markdownText = res.data.articleContent;
            this.article = res.data

            this.renderMarkdown(); // 在这里调用 renderMarkdown()  
        }).catch((error) => {
            console.error('Error fetching article:', error);
        }).finally(() => {
            this.markedButton()
        });

    },
    methods: {
        // 格式化日期
        formatDate(value) {
            if (!value) return '';
            const date = new Date(value);
            return date.toLocaleString('zh-CN', { hour12: false }); // 你可以根据需要调整日期时间格式  
        },
        // 复制代码
        async copyCode(currentCode) {
            if (navigator.clipboard) {
                try {
                    await navigator.clipboard.writeText(currentCode);
                } catch (error) {
                    console.error(error);
                }
            } else {
                console.error('当前浏览器不支持此API');
            }
        },
        // 渲染Markdown
        renderMarkdown() {
            if (!marked) {
                console.error('marked is not defined');
                return;
            }
            // 初始化marked
            const renderer = new marked.Renderer();
            // 初始化highlight.js
            marked.setOptions({
                renderer: renderer,
                langPrefix: 'hljs language-',
                pedantic: false,
                gfm: true,
                breaks: false,
                sanitize: false,
                smartLists: true,
                smartypants: false,
                xhtml: false,
                // 自定义渲染器
                extensions: {
                    renderers: {
                        ["code"]: function (code) {
                            return ` <figure class="highlight ${code.lang}" code-info="📟  © 安奈博客🌙">  
                        <figcaption><span> ${code.lang || 'yaml'} </span></figcaption>  
                        <table>  
                        <tbody>  
                        <tr>  
                        <td class="gutter"></td>
                        <td class="code">  
                        <pre><code class="hljs ${code.lang}">${hljs.highlight(code.text, { language: code.lang }).value} </code></pre> 
                        </td>  
                        </tr>  
                        </tbody>  
                        </table> 
                        </figure>`;
                        }
                    },
                }
            });
            // 渲染Markdown
            this.renderedMarkdown = marked(this.markdownText);
        },
        //设置Markdown按钮
        markedButton() {
            const codeElements = document.querySelectorAll('td.code');
            // 遍历code元素
            codeElements.forEach(async (code, index) => {
                let figure = code.parentElement.parentElement.parentElement.parentElement;  // 整个figure代码块标签
                const preCode = code.querySelector('pre').firstElementChild;  // 代码元素
                let preGutter = code.parentElement.firstElementChild;  // 行号元素
                preCode.id = `${index + 1}`;  // 设置id，未来用
                // 隐藏多余的代码只显示6行
                preCode.setAttribute('style', 'display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6; overflow: hidden;');
                // 修改code标签的before伪类
                const setPreCodeBefore = (msg = '优雅借鉴') => {
                    preCode.setAttribute('code-msg', msg)
                }
                // 初始化展开/收起按钮
                setPreCodeBefore()
                // 添加展开/收起按钮
                if (preCode.innerHTML.split('\n').length > 6) {
                    // 展开/收起按钮添加到figure标签的最后一个子节点
                    const codeCopyDiv = document.createElement('div');
                    codeCopyDiv.classList.add('CodeCloseDiv');
                    figure.appendChild(codeCopyDiv);
                    var codeCopyOver = document.createElement('button');
                    codeCopyOver.classList.add('CodeClose');
                    codeCopyOver.innerHTML = this.openText;
                    figure.childNodes.item(5).appendChild(codeCopyOver)
                    // 展开/收起代码回执位置
                    await codeCopyOver.addEventListener('click', async () => {
                        if (codeCopyOver.innerHTML === this.openText) {
                            setPreCodeBefore('右上角可全屏亦可下载')
                            // 展开代码回执位置
                            preCode.setAttribute('style', 'display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 99999; overflow: hidden;'); preGutter.style.overflow = 'visible'
                            codeCopyOver.innerHTML = this.closeText;
                        } else {
                            setPreCodeBefore()
                            preCode.setAttribute('style', 'display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6; overflow: hidden;'); preGutter.style.overflow = 'hidden';
                            codeCopyOver.innerHTML = this.openText;
                        }
                    });
                }
                // 添加复制按钮
                const codeCopyBtn = document.createElement('div');
                codeCopyBtn.classList.add('copy-btn');
                codeCopyBtn.classList.add('more-btn');
                codeCopyBtn.innerHTML = this.copyText;
                code.appendChild(codeCopyBtn);
                code.appendChild(codeCopyBtn);

                // 添加复制功能
                codeCopyBtn.addEventListener('click', async () => {
                    const currentCodeElement = code.querySelector('pre')?.innerText;
                    await this.copyCode(currentCodeElement);
                    codeCopyBtn.innerHTML = this.copySuccess;
                    codeCopyBtn.classList.add('success');
                    setPreCodeBefore('借鉴成功')
                    // 3秒后恢复
                    setTimeout(() => {
                        codeCopyBtn.innerHTML = this.copyText;
                        codeCopyBtn.classList.remove('success');
                        setPreCodeBefore()
                    }, 3000);
                });

                // 添加全屏按钮
                const codeFullBtn = document.createElement('div');
                codeFullBtn.classList.add('full-btn');
                codeFullBtn.classList.add('more-btn');
                codeFullBtn.innerHTML = this.fullOpen;
                code.appendChild(codeFullBtn);
                const fullEvents = ['fullscreenchange', 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange']
                // 添加全屏功能与监听用户退出全屏， 退出则控制台输出日志
                codeFullBtn.addEventListener('click', async () => {
                    // 全屏状态
                    if (codeFullBtn.innerHTML === this.fullClose) {
                        codeFullBtn.innerHTML = this.fullOpen;
                        setPreCodeBefore()
                        await exitFullscreen();
                    } else {
                        // 尝试全屏代码
                        try {
                            // 如果当前元素支持全屏API
                            await openFullscreen()
                            if (codeCopyOver && codeCopyOver.innerHTML === this.openText) {
                                codeCopyOver.click()
                            }
                            setPreCodeBefore('ESC键退出全屏')
                            codeFullBtn.innerHTML = this.fullClose
                            // 监听全屏状态变化事件
                            fullEvents.forEach(event => document.addEventListener(event, handleFullscreenChange));

                        } catch (err) {
                            console.error('全屏请求失败：', err);
                        }
                    }
                });

                // 处理全屏状态变化事件
                const handleFullscreenChange = () => {
                    if (!document.fullscreenElement && !document.mozFullScreenElement &&
                        !document.webkitFullscreenElement && !document.msFullscreenElement) {
                        if (codeCopyOver && codeCopyOver.innerHTML === this.closeText) {
                            codeCopyOver.click()
                        }
                        if (codeFullBtn.innerHTML === this.fullClose) {
                            codeFullBtn.innerHTML = this.fullOpen;
                        }
                        // 在这里执行用户退出全屏后的操作
                        // 例如：移除全屏事件监听器
                        fullEvents.forEach(event => document.removeEventListener(event, exitFullscreen));
                    }
                }
                // 在需要的时候主动开启全屏
                const openFullscreen = async () => {
                    await (figure.requestFullscreen() || figure.mozRequestFullScreen() || figure.webkitRequestFullscreen() || figure.msRequestFullscreen());
                }
                // 在需要的时候主动关闭全屏
                const exitFullscreen = async () => {
                    await (document.exitFullscreen() || document.mozCancelFullScreen() || document.webkitExitFullscreen() || document.msExitFullscreen());
                }

                // 添加下载按钮
                const codeDownBtn = document.createElement('div');
                codeDownBtn.classList.add('down-btn');
                codeDownBtn.classList.add('more-btn');
                codeDownBtn.innerHTML = this.downTest;
                code.appendChild(codeDownBtn);
                // 创建 Blob 对象
                let blob = new Blob([code.innerText], { type: 'text/plain' });
                // 格式化文件大小
                const formatFileSize = (sizeInBytes) => {
                    const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
                    let size = sizeInBytes;
                    let unitIndex = 0;
                    while (size >= 1024 && unitIndex < units.length - 1) {
                        size /= 1024;
                        unitIndex++;
                    }
                    return `${size.toFixed(2)} ${units[unitIndex]}`;
                }
                // 添加figure的after伪类
                this.FileSize = formatFileSize(blob.size)

                codeDownBtn.addEventListener('click', () => {
                    const figcaption = figure.firstElementChild
                    const fileNamePattern = /^[^\\/]+\.\w+$/;
                    let fileName = figcaption.tagName === 'FIGCAPTION' ? figcaption.innerText : '钟意博客';
                    if (!fileNamePattern.test(fileName)) {
                        const suffix = window.getComputedStyle(code, ':before').getPropertyValue('content').replaceAll('"', '').toLowerCase() || '';
                        fileName += (suffix !== undefined && suffix !== '' ? '.' + suffix : '')
                    }
                    fileName = fileNamePattern.test(fileName) ? fileName : `${fileName}.txt`;
                    // 创建下载链接
                    const downloadLink = document.createElement('a');
                    downloadLink.href = URL.createObjectURL(blob);
                    // 设置文件名
                    downloadLink.download = fileName;
                    // 将链接添加到页面
                    document.body.appendChild(downloadLink);
                    // 模拟点击下载链接
                    downloadLink.click();
                    // 移除链接元素
                    document.body.removeChild(downloadLink);
                    setPreCodeBefore("下载成功，Ctrl+J 查收")
                    codeDownBtn.classList.add('success')
                    setTimeout(() => {
                        codeDownBtn.classList.remove('success');
                        setPreCodeBefore()
                    }, 3000);
                });
            });
        }
    },
}
</script>
<style lang="scss">
@import url('@/assets/css/code.css');
</style>